назад

DirectX против OpenGL

Антиподы или близнецы-братья?

В технических характеристиках можно часто прочитать, что видеокарта поддерживает DirectX и OpenGL последних версий. А что это значит? Зачем поддерживать сразу две библиотеки? В чем заключается разница между ними? Попробуем ответить на эти вопросы.

Все современные видеокарты имеют аппаратную поддержку возможностей DirectX и OpenGL последних версий, причем для совместимости с разным софтом (использующим ту или иную версию) производители встраивают в чипы реализацию сразу обеих библиотек. Различия их состоят в способе обработки графической информации, причем от версии к версии добавляются новые функции и возможности, позволяющие создавать более реалистичную графику. Чтобы выполнить обработку (весьма сложную) графической информации и снять с программистов заботу разработки собственного драйвера для доступа к функциям видеокарты и были созданы данные библиотеки.

Что это такое?

Что же все-таки скрывается за словами OpenGL и DirectX? Слова эти именуют те самые Application Programming Interface (API - Интерфейс Прикладного Программирования), библиотеки для обработки графической информации и прямого доступа к железу («software interface to graphics hardware», как обозначаются они в спецификации). Думаю, не надо объяснять, что библиотеки содержат набор уже однажды написанных функций, от самых простых (вывод точки на экран) до довольно сложных (построение готовых примитивов, например, трехмерной пирамидки), которые применяются практически в каждой программе. Базовые функции реализованы аппаратно, в виде части GPU, более сложные функции представляют собой программные модули, построенные на базовых командах. Видеокарта не всегда аппаратно поддерживает нужные для работы приложения функции, и в этом случае библиотека использует программные модули, эмулирующие требующиеся возможности.

Если попытаться объяснить понятным языком общую схему работы библиотеки (рис. 1), то она выглядит примерно так: программист дал команду сделать Tri-linear Filtering (трилинейную фильтрацию – уменьшить искажения в картах текстур). Программа вызывает графическую часть DirectX (Direct3D) и предает библиотечной функции данные и что нужно с ними сделать. Модуль библиотеки, отвечающий за работу с драйвером видеокарты, в свою очередь, передает ему необходимые данные и «выясняет», аппаратно или программно будет происходить обработка. Драйвер «видит», что D3D этой версии полностью поддерживается на железном уровне и «отвечает», что есть аппаратная поддержка, и «передает» информацию дальше – видеоадаптеру. Но на этой стадии разработчики видеокарты и драйвера могут внести в процесс свои коррективы. Например, Tri-linear Filtering – очень ресурсоемкая операция, поэтому на уровне драйверов она заменяется менее точной, но более быстрой Bri-linear Filtering (брилинейная фильтрация, реализована на картах ATi). И дальше драйвер «кладет» в регистры GPU все данные, которые обрабатываются в соответствии с запросом, после чего во framebuffer поступает двухмерный кадр, который и выводится на монитор.

Конечно, такая схема работы довольно сложна, и можно было бы самому обратиться к видеоплате, однако современные ОС, заботясь о стабильности, блокируют прямой доступ к аппаратным частям компьютера, то есть, чтобы работать с каким-либо устройством, требуется написать драйвер, а это уже не так просто. К тому же при прямом доступе к железу все операции по обработке графики проходят в разы быстрее, поскольку просчет производится непосредственно адаптером. Поэтому для работы с графической информацией и были написаны данные библиотеки, причем в разработке принимали участие многие крупные компании.

Основу обоих API составляют несколько файлов, в которых содержатся как низкоуровневые функции (типа вывода пикселя на экран), так и более сложные модули (типа рисования линии, состоящей из множества пикселей).

Немного истории

Чтобы лучше понять, чего можно ждать от реализации обоих API, обратимся к истокам их создания.

OpenGL. Этот API Основан на стандарте IRIS GL, разработанном корпорацией Silicon Graphics Incorporated (SGI). Окончательно спецификация оформилась в 1992 году (30 июня релиз версии 1.0). В OpenGL (Open Graphics Library - Открытая Графическая Библиотека) закладывалась идея создания аппаратно-независимого интерфейса, то есть единожды написанные программы могли бы без проблем работать на различных платформах. Сегодня развитием OpenGL занимается Architectural Review Board (ARB - Комитет Пересмотра Архитектуры), куда входят такие известные компании как 3D Labs, SGI, Apple, nVIDIA, ATi, Intel, id Software, Microsoft.

Открытая Графическая Библиотека нашла свое применение во многих областях (не только игровой индустрии), и уже 12 лет остается востребованной, но сегодня ARB несколько «тормозит» развитие стандарта, поскольку для добавления/удаления каких-либо основополагающих понятий нужно провести большое количество согласований среди входящих в комитет компаний. Однако разработчики графического железа вышли из положения, создав extensions (расширения) для получения доступа к новым функциям. Скоро ожидается версия OpenGL 2.0, которая предполагает множество революционных изменений, и уже полным ходом идет процесс ее стандартизации.

DirectX. Эта библиотека является изобретением компании RenderMorphic, приобретенным Microsoft. Потребность в дополнительном графическом API возникла из-за изначальной ограниченности программирования игр под Windows 95 (а вернее, из-за медленной обработки мультимедиа данных). Поначалу Game Software Development Kit (Game SDK) позиционировался, как «идеальное решение для создания игр». Конечно же, DirectX 1.0 (впрочем, как и 2, и 3) не мог конкурировать с OpenGL, и поначалу это была медленная, сложная и довольно «дырявая» библиотека. Продвижение DirectX началось с седьмой версии, когда реализация интерфейсов между программной и аппаратной частью стала быстрее и удобнее в программировании. Сейчас эта библиотека является достаточно мощной и стабильной (причем по большей части ее пишут программисты, работающие над Windows).

На данный момент обе библиотеки являются мощными разработками с равным потенциалом. Нельзя сказать, кто лучше, кто хуже, также у обеих разработок имеется набор специфических, только им присущих «фишек».

Основные принципы работы

OpenGL. Изначально это только графическая библиотека. Основой для этой API является ядро, которое «умеет» обрабатывать примитивные объекты (как правило, треугольники). Сам интерфейс (для программиста) содержит много (порядка нескольких сотен) процедур и функций, необходимых для создания высококачественных графических изображений. Чтобы аппаратно реализовать многие функции (например, antialiasing или texturing) от видеокарты требуется наличие framebuffer'а (кадровый буфер), причем некоторые операции могут выполняться исключительно в нем.

Для работы с библиотекой программа сначала должна открыть окно во framebuffer (где будет происходить все операции), и потом уже контекст библиотеки связывается с этим окном. Такую операцию нужно проделать один раз, а далее все действия определяются через параметры обработки (рисование простых геометрических объектов: линии, точки, полигоны; рендеринг примитивов, включая их положение и цвет).

Для разработчика процессора видеокарты OpenGL является набором команд, которые влияют на работу графического железа. Если в наличии имеется только адресуемый framebuffer, то библиотека должна быть встроена в GPU. Чаще же плата содержит еще и графический ускоритель (состоящий из растровой подсистемы, которая занимается render'ом 2D линий и полигонов). Графические процессоры способны лишь просчитывать и трансформировать геометрические данные (аналог элементарных операций, с которыми умеет работать обычный CPU - сложение и присваивание). Задачей создателя графической платы является разработка программного интерфейса GPU для разделения обработки команд OpenGL между GPU и остальным графическим железом. Такое деление должно быть специально оптимизировано под выполнение команд библиотеки.

Сама же библиотека реализована в виде информации о структуре, определяющей, как объекты будут нарисованы во framebuffer, причем некоторые из структур доступны пользователю, который может создавать различные вызовы процедур для изменения параметров.

Чуть выше мы рассмотрели, как вообще работает библиотека, сейчас же остановимся на простом примере - рисование текстурированной пирамиды средствами OpenGL. Для этого посмотрим на базовые понятия (не забывая рисунок 2), требующиеся программисту для выполнения этой задачи:

Vertex (вершины) - образуются после указания координат в 2-х, 3-х или 4-мерном пространстве. В нашем случае мы задаем четыре координаты в 3D пространстве, которые обозначают вершины фигуры.

Vertex Arrays (массив вершин) – для работы с множеством вершин требуется обрабатывать большое количество команд (для образования простых геометрических фигур), чтобы избежать ненужной вычислительной нагрузки существует объединение вершин. В этом случае из них образуется массив, который содержится в памяти. Для работы с пирамидой в целом вершины объединяются под единым именем.

Buffer Objects (буферные объекты) – если требуется сохранить данные (те же Vertex Arrays) в быстрой памяти видеоадаптера для последующего повторного использования, существуют Buffer Objects, которые осуществляют распределение, инициализацию и извлечение информации об объекте из памяти.

Evaluators – средства для множественных преобразования координат и цвета. После создания четырех вершин определяются команды для обработки (которые записываются в Display List) и проводятся усреднения и просчет геометрической поверхности (на этом шаге уже появляется каркас объекта).

Coordinate Transformation (трансформация координат) – все объекты перед выводом во framebuffer претерпевают изменение своих координат (из их программного представления в «оконное» для framebuffer), схема такого преобразования представлена на рисунке 3. Причем в этот момент происходит подготовка к растеризации (обрезаются лишние части фигуры, которые вылезают за экран).

Rasterization – процесс, в котором вся картинка преобразовывается к 2D виду. Растеризатор обрабатывает объект, раскрашивает его, накладывает текстуру, и на выходе получается кадр, который далее поступает во framebuffer, а уже оттуда на монитор.

То есть видно, что программист последовательно определяет только основные параметры для той или иной операции. Дальнейшее происходит без его участия, средствами библиотеки, драйвера и, наконец, видеоадаптера.

FrameBuffer (кадровый буфер) - некая область памяти для временного хранения информации о точках, составляющих один кадр изображения на мониторе. Открыть окно во FB – это значит распределить видеопамять под изображение.

DirectX. Этот API является комплексной библиотекой, которая содержит в себе интерфейсы (для программиста) по обработке не только графики. Мы же рассматриваем только графическую ее часть.

Так же как и OpenGL, DirectX на низком уровне взаимодействует с аппаратной частью компьютера и предоставляет программисту набор интерфейсов для обработки графики, однако большим отличием от конкурента является использование Component Object Model (COM). То есть для работы с изображением нужно не просто вызвать определенную функцию или процедуру, а провести еще ряд дополнительных манипуляций для получения доступа к объектам (работа с которыми происходит только через интерфейсы), а после этого каждому объекту нужно заполнить некий набор необходимых свойств, без которых он является неопределенным. Актуальными все эти шаги являются только для программиста, поскольку после компиляции программы команды на обработку графики (для драйвера и видеоплаты) идут последовательно, вне зависимости от того, как было создано приложение.

Чтобы начать работать с графической библиотекой, требуется открыть окно программы, но далее нужно также создать устройство отрисовки и тем самым произвести инициализацию Direct3D. После выполнения этого шага идет процесс просчета и отображения сцены.

На аппаратном уровне API выполняется следующим образом: D3D обеспечивает независимость от Hardware Abstraction Layer (HAL - аппаратный уровень абстракции). HAL – это железо-зависимый интерфейс (не поддерживающий эмуляции), который разрабатывается создателем видеоадаптера и включает в себя поддержку D3D. В данном случае Microsoft описала, как должна быть реализована D3D аппаратно, а уже производители реализуют нужные функции в своих чипах. То есть получается такая ситуация, когда программа ничего не знает об установленном оборудовании и напрямую с ним не взаимодействует.

HAL может содержать три разных типа модели обработки вершин (на одном устройстве) - программный, аппаратный (который зависит от конкретного девайса) и смешанный. Аппаратный тип поддерживает только обработку вершин и дает возможность небольших изменений состояния устройства по запросу приложения. Кроме использования возможностей видеокарты, DirectX в полной мере пользуется инструкциями AMD 3DNow! и Intel Pentium SIMD (одна команда – много данных), которые включены в обработку некоторых вершинных шейдеров.

Для создания сцены потребуется инициализировать D3D объект для рисования, включая создание объекта, указание параметров отображения, создание D3D устройства, причем в параметрах устройства можно указать способ обработки вершин – аппаратный или программный. Далее производятся похожие с OpenGL преобразования, но с учетом того, что все операции работают над объектами. При завершении программы нужно закрыть устройство, но на деле все же этот процесс выглядит немного сложнее.

В последней версии DirectX появились интересные возможности, увеличивающие реалистичность графики:

HLSL (High-Level Shader Language - Высокоуровневый Язык Шейдеров) - позволяет управлять потоком команд;

Контроль над выполнением шейдера;

Взаимодействие с GDI (Graphics Device Interface);

Поддержка замещающих карт (Displacement mapping) - изменение координат полигона;

Поддержка 40-битного цвета (более 1.0 млрд. цветов).

Pixel Shaders - это небольшие подпрограммы (выполняются на графическом процессоре), которые работают с каждым пикселем при создании текстуры и применяются для просчета света, создания различных эффектов. В библиотеке OpenGL они отсутствуют по причине того, что когда создавалась спецификация, шейдеры еще не были придуманы, и поэтому сегодня их включили в виде расширений.

Отличия. По своей сути обе библиотеки различаются обработкой графической информации, и если OpenGL – это процедурная система, то DirectX основан на COM-модели. Однако, даже несмотря на различную природу работы с информацией, обе они «заточены» под взаимодействие с «железом». OpenGL не поддерживает Pixel Shaders, однако это не повод отказываться от работы с этой библиотекой (пример тому Unreal Tournament, движок которого построен на основе OpenGL). Библиотека DirectX умеет эмулировать некоторые функции, не поддерживаемые аппаратно, однако на пиксельном уровне это неосуществимо и программа должна сама проверять возможности такой эмуляции. Чтобы внедрять новые технологии, у OpenGL существует механизм расширений, когда различные функции (недоступные изначально, но реализованные аппаратно) разрабатываются производителем железа и поддерживаются спецификацией для конкретной модели видеоадаптера. В DirectX система немного другая - версия библиотеки может содержать или не содержать определенных функций (даже если они присутствуют в железе) и для их поддержки требуется ждать нового релиза DX, однако Microsoft активно общается с производителями видеокарт, и такая ситуация возникает достаточно редко.

То есть, хотя поддержка на уровне железа и реализована по-разному (различается как реализация базовых функций, так и фирменные технологии, направленные на улучшение качества графики), выявить лучший механизм сложно, поскольку новые функции OpenGL доступны лишь через extensions, тогда как у DirectX приходится ждать новой версии библиотеки.

Программная поддержка

OpenGL. Поскольку эта библиотека разрабатывалась группой компаний, она является мультиплатформенной и поддерживается большим количеством языков программирования (включая Java, Perl, Python), операционных систем (Windows, Macintosh, *nix). Причем любой производитель видеоадаптеров может купить лицензию и выпустить свою версию OpenGL не только для компьютера, но и для других устройств (существуют реализации под игровые консоли, КПК и даже телефоны). Причем ARB рассматривает большинство расширений, созданных производителями железа, и всегда есть вероятность их включения в спецификацию следующей версии библиотеки.

DirecX. Это детище одной лишь Microsoft, и соответственно официальная поддержка только операционных систем семейства Windows и платформы XBox. И исходя из такой монопольности, развитием и внедрением новых функций занимается только эта корпорация.

Точка зрения программиста

Если посмотреть на программную реализацию обоих библиотек, то можно сделать единственный вывод: программировать приложения с использованием OpenGL гораздо легче, чем писать их под DirectX (для примера: чтобы нарисовать обыкновенный треугольник на экране с использованием DirectX нужно написать почти в 5 раз больше текста, чем с использованием OpenGL). Правда, разработчики D3D постоянно пытаются облегчить работу программистов, объединяя наиболее часто используемые вызовы и операции в Common Files.

Выводы

Итак, обе библиотеки облегчают работу конечного программиста и обеспечивают интерфейс программы с конкретным железом. Они не совместимы между собой и имеют свои фирменные особенности, поэтому производителям приходится реализовывать в своих ядрах базовые функции обоих API, причем учитывать дополнительные функции новых версий и расширений.

Окончательно можно сделать следующий вывод: обе библиотеки достаточно мощные и производительные, но их преимущества проявляются в разных областях. DirectX оптимально подходит для создания игр и других графических приложений под операционной системой Windows (что чаще всего и происходит), OpenGL же лучше всего проявляет себя на мощных рабочих станциях и там, где требуется совместимость приложений с различными платформами (как программная, так и аппаратная). Хотя и в сфере игр эта библиотека так же достаточно востребована (Doom III, Unreal Tournament 2004).

В будущем планируется использование «железа», программируемого при помощи языка HLSL – High Level Shading Language у DirectX 9 и программирования графического конвейера на языке высокого уровня OpenGL версии 2.0, что должно поднять уровень графики на новую высоту.

Основными изменениями в OpenGL 2.0 станет поддержка программируемых GPU (то есть в процессе обработки картинки можно будет управлять поведением пиксельного конвейера), управление памятью и сжатием пикселей (pixel packing), что позволит уменьшить занимаемый текстурой объем памяти. Реализовано это будет через новый высокоуровневый язык (который, как и библиотека, останется независимым от аппаратной платформы). Так же планируется включить в стандарт OpenML - набор функций, добавляющий возможность обработки видео.

Будет два вида второй версии библиотеки - Pure OpenGL 2.0 и OpenGL 2.0, отличаться они будут тем, что в первую будет включена полная спецификация версии 1.3 (сделано это для сглаживания процесса перехода к новой спецификации), а вторая будет лишена всех ненужных функций.

Microsoft включает в Windows библиотеки OpenGL, причем версии «слегка» устаревшей, которая ко всему прочему не использует аппаратные возможности ускорения, это серьезное «упущение» исправляют драйверы графических ускорителей.

Полезные ссылки:

http://www.microsoft.com/directx - официальная страница DirectX.

http://msdn.microsoft.com/directx - документация и статьи по DirectX.

http://www.opengl.org – официальная страница OpenGL.

http://www.ati.com/developer - поддержка разработчиков приложений под видеоадаптеры ATI.

http://developer.nvidia.com/page/home - поддержка разработчиков приложений под видеоадаптеры nVIDIA.

назад
macolor site